package com.fingard.dsp.bank.directbank.weixin01;

import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.ReqQueryOrder;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.ReqUnifiedOrder;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.RetAtsQueryOrder;
import com.fingard.dsp.bank.reqrespobj.unifiedorder.RetAtsUnifiedOrder;
import com.fingard.text.StringHelper;
import com.fingard.text.XmlHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XmlTextReader;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

/**
 * WEIXIN01-微信财付通渠道统一下单
 */
public class WxUnifiedOrder extends WEIXIN01Base {
    public RetAtsUnifiedOrder submitUnifiedOrder(ReqUnifiedOrder p_req) {
        RetAtsUnifiedOrder retAts = new RetAtsUnifiedOrder();
        retAts.rdSeq = p_req.rdSeq;

        String submitUrl = "unifiedorder";

        try {
            ActSetItem actItem = getBankConfig().getActSetItemByAny(p_req.ownAct, p_req.merchantId, p_req.appId, "unifiedorder");
            if (actItem != null) {
                ArrayList<String> arrayParams = new ArrayList<String>();

                StringBuilder sbXml = new StringBuilder();
                sbXml.append("<xml>\r\n");

                String appid = p_req.appId;
                if (StringHelper.isNullOrEmpty(appid)) {
                    appid = actItem.appId;
                }
                sbXml.append("  <appid>" + appid + "</appid>\r\n");
                arrayParams.add("appid=" + appid);

                String mch_id = p_req.merchantId;
                if (StringHelper.isNullOrEmpty(mch_id)) {
                    mch_id = actItem.merchantId;
                }
                sbXml.append("  <mch_id>" + mch_id + "</mch_id>\r\n");
                arrayParams.add("mch_id=" + mch_id);

                if ("01".equalsIgnoreCase(p_req.signType) || "02".equalsIgnoreCase(p_req.signType)) {
                    submitUrl = "contractorder";

                    sbXml.append("  <contract_mchid>" + mch_id + "</contract_mchid>\r\n");
                    arrayParams.add("contract_mchid=" + mch_id);

                    sbXml.append("  <contract_appid>" + appid + "</contract_appid>\r\n");
                    arrayParams.add("contract_appid=" + appid);

                    String notifyUrl = "";
                    if ("01".equalsIgnoreCase(p_req.signType)) {
                        notifyUrl = actItem.notifyURLMap.get("contractjsapi");
                    } else if ("02".equalsIgnoreCase(p_req.signType)) {
                        notifyUrl = actItem.notifyURLMap.get("contracth5");
                    }
                    if (StringHelper.hasAnyChar(notifyUrl)) {
                        sbXml.append("  <notify_url>" + notifyUrl + "</notify_url>\r\n");
                        arrayParams.add("notify_url=" + notifyUrl);
                    }

                    if (StringHelper.hasAnyChar(p_req.clientIp)) {
                        sbXml.append("  <spbill_create_ip>" + p_req.clientIp + "</spbill_create_ip>\r\n");
                        arrayParams.add("spbill_create_ip=" + p_req.clientIp);
                    }

                    String transType = "";
                    if ("01".equalsIgnoreCase(p_req.signType)) {
                        transType = "JSAPI";
                    } else if ("02".equalsIgnoreCase(p_req.signType)) {
                        transType = "MWEB";
                    }
                    if (StringHelper.hasAnyChar(transType)) {
                        sbXml.append("  <trade_type>" + transType + "</trade_type>\r\n");
                        arrayParams.add("trade_type=" + transType);
                    }

                    if ("JSAPI".equals(transType)) {
                        if (StringHelper.hasAnyChar(p_req.openid)) {
                            sbXml.append("  <openid>" + p_req.openid + "</openid>\r\n");
                            arrayParams.add("openid=" + p_req.openid);
                        } else {
                            if (StringHelper.isNullOrEmpty(p_req.code)) {
                                retAts.respCode = "-1";
                                retAts.respInfo = "Code和Openid不能同时为空";

                                return retAts;
                            } else {
                                if (StringHelper.isNullOrEmpty(actItem.appSecret)) {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "未配置公众号的appsecret";

                                    return retAts;
                                } else {
                                    HashMap<String, String> hashOpenid = getOpenid(appid, actItem.appSecret, p_req.code);

                                    if (hashOpenid.get("RespCode").equals("0")) {
                                        if (hashOpenid.containsKey("openid")) {
                                            sbXml.append("  <openid>" + hashOpenid.get("openid") + "</openid>\r\n");
                                            arrayParams.add("openid=" + hashOpenid.get("openid"));
                                        } else {
                                            retAts.respCode = "-1";
                                            retAts.payInfoCode = FailCode.E9981;

                                            String errcode = "";
                                            if (hashOpenid.containsKey("errcode")) {
                                                errcode = hashOpenid.get("errcode");
                                            }

                                            String errmsg = "";
                                            if (hashOpenid.containsKey("errmsg")) {
                                                errmsg = hashOpenid.get("errmsg");
                                            }
                                            retAts.respInfo = StringHelper.joinNotEmpty("-", errcode, errmsg);
                                            retAts.transState = PaymentState.FAIL_Payment;
                                            return retAts;
                                        }
                                    } else {
                                        retAts.respCode = "-1";
                                        retAts.respInfo = hashOpenid.get("RespInfo");
                                        return retAts;
                                    }
                                }
                            }
                        }
                    }

                    if (StringHelper.hasAnyChar(p_req.planId)) {
                        String planId = XmlHelper.encode(p_req.planId);
                        sbXml.append("  <plan_id>" + planId + "</plan_id>\r\n");
                        arrayParams.add("plan_id=" + planId);
                    }

                    if (StringHelper.hasAnyChar(p_req.authCode)) {
                        String authCode = XmlHelper.encode(p_req.authCode);
                        sbXml.append("  <contract_code>" + authCode + "</contract_code>\r\n");
                        arrayParams.add("contract_code=" + authCode);
                    }

                    if (StringHelper.hasAnyChar(p_req.serialNo)) {
                        String serialNo = XmlHelper.encode(p_req.serialNo);
                        sbXml.append("  <request_serial>" + serialNo + "</request_serial>\r\n");
                        arrayParams.add("request_serial=" + serialNo);
                    }

                    if (StringHelper.hasAnyChar(p_req.oppActName)) {
                        String oppActName = XmlHelper.encode(p_req.oppActName);
                        sbXml.append("  <contract_display_account>" + oppActName + "</contract_display_account>\r\n");
                        arrayParams.add("contract_display_account=" + oppActName);
                    }

                    String signNotifyUrl = "";
                    if ("01".equalsIgnoreCase(p_req.signType)) {
                        signNotifyUrl = actItem.notifyURLMap.get("contractjsapisign");
                    } else if ("02".equalsIgnoreCase(p_req.signType)) {
                        signNotifyUrl = actItem.notifyURLMap.get("contracth5sign");
                    }
                    if (StringHelper.hasAnyChar(signNotifyUrl)) {
                        sbXml.append("  <contract_notify_url>" + signNotifyUrl + "</contract_notify_url>\r\n");
                        arrayParams.add("contract_notify_url=" + signNotifyUrl);
                    }

                    if ("1".equals(p_req.realNameFlag)) {
                        if (StringHelper.isNullOrEmpty(p_req.region)) {
                            // 非车险实名,无需传入以下字段
                            if (StringHelper.hasAnyChar(p_req.certNumber)) {
                                sbXml.append("  <user_creid>" + p_req.certNumber + "</user_creid>\r\n");
                                arrayParams.add("user_creid=" + p_req.certNumber);
                            }

                            if (StringHelper.hasAnyChar(p_req.oppActName)) {
                                sbXml.append("  <user_truename>" + p_req.oppActName + "</user_truename>\r\n");
                                arrayParams.add("user_truename=" + p_req.oppActName);
                            }
                        }
                    } else if ("0".equals(p_req.realNameFlag)) {
                        // 非实名
                    } else {
                        if (StringHelper.hasAnyChar(p_req.oppActName) || StringHelper.hasAnyChar(p_req.certNumber)) {
                            // 普通实名
                            if (StringHelper.hasAnyChar(p_req.certNumber)) {
                                sbXml.append("  <user_creid>" + p_req.certNumber + "</user_creid>\r\n");
                                arrayParams.add("user_creid=" + p_req.certNumber);
                            }

                            if (StringHelper.hasAnyChar(p_req.oppActName)) {
                                sbXml.append("  <user_truename>" + p_req.oppActName + "</user_truename>\r\n");
                                arrayParams.add("user_truename=" + p_req.oppActName);
                            }
                        }
                    }
                } else {
                    String notify_url = actItem.notifyURLMap.get("");
                    if (StringHelper.hasAnyChar(notify_url)) {
                        sbXml.append("  <notify_url>" + notify_url + "</notify_url>\r\n");
                        arrayParams.add("notify_url=" + notify_url);
                    }

                    if (StringHelper.hasAnyChar(p_req.cur)) {
                        sbXml.append("  <fee_type>" + p_req.cur + "</fee_type>\r\n");
                        arrayParams.add("fee_type=" + p_req.cur);
                    }

                    //	APP和网页支付提交用户端IP，Native支付填调用微信支付API的机器IP。
                    if (reqHeader.transType.equals("SubmitH5Order")) {
                        sbXml.append("  <spbill_create_ip>" + p_req.clientIp + "</spbill_create_ip>\r\n");
                        arrayParams.add("spbill_create_ip=" + p_req.clientIp);
                    } else {
                        sbXml.append("  <spbill_create_ip>" + actItem.createIP + "</spbill_create_ip>\r\n");
                        arrayParams.add("spbill_create_ip=" + actItem.createIP);
                    }

                    // H5支付的交易类型为MWEB
                    String trade_type = "";
                    if (reqHeader.transType.equals("SubmitH5Order")) {
                        trade_type = "MWEB";
                    } else if (reqHeader.transType.equals("SubmitJSAPIOrder") || reqHeader.transType.equals("SubmitMiniProgOrder") || reqHeader.transType.equals("SubmitWXMiniProgOrder")) {
                        trade_type = "JSAPI";
                    } else if (reqHeader.transType.equals("SubmitQROrder")) {
                        trade_type = "NATIVE";
                    } else if (reqHeader.transType.equals("SubmitAPPOrder")) {
                        trade_type = "APP";
                    }
                    sbXml.append("  <trade_type>" + trade_type + "</trade_type>\r\n");
                    arrayParams.add("trade_type=" + trade_type);

                    if ("1".equals(p_req.realNameFlag)) {
                        if (StringHelper.isNullOrEmpty(p_req.region)) {
                            // 非车险实名
                            if (StringHelper.hasAnyChar(p_req.certNumber)) {
                                sbXml.append("  <user_creid>" + p_req.certNumber + "</user_creid>\r\n");
                                arrayParams.add("user_creid=" + p_req.certNumber);
                            }

                            if (StringHelper.hasAnyChar(p_req.oppActName)) {
                                sbXml.append("  <user_truename>" + p_req.oppActName + "</user_truename>\r\n");
                                arrayParams.add("user_truename=" + p_req.oppActName);
                            }
                        }
                    } else if ("0".equals(p_req.realNameFlag)) {
                        // 非实名
                    } else {
                        if (StringHelper.hasAnyChar(p_req.oppActName) || StringHelper.hasAnyChar(p_req.certNumber)) {
                            // 普通实名
                            if (StringHelper.hasAnyChar(p_req.certNumber)) {
                                sbXml.append("  <user_creid>" + p_req.certNumber + "</user_creid>\r\n");
                                arrayParams.add("user_creid=" + p_req.certNumber);
                            }

                            if (StringHelper.hasAnyChar(p_req.oppActName)) {
                                sbXml.append("  <user_truename>" + p_req.oppActName + "</user_truename>\r\n");
                                arrayParams.add("user_truename=" + p_req.oppActName);
                            }
                        }
                    }

                    // scene_info
                    if (reqHeader.transType.equals("SubmitH5Order")) {
                        String scene_info = getBankConfig().getValueAsString("scene_info");
                        if ("".equals(scene_info)) {
                            scene_info = "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"http://pay.epicc.com.cn\",\"wap_name\": \"PICC人保财险官网\"}}";
                        }
                        sbXml.append("  <scene_info>" + scene_info + "</scene_info>\r\n");
                        arrayParams.add("scene_info=" + scene_info);
                    } else if (reqHeader.transType.equals("SubmitJSAPIOrder") || reqHeader.transType.equals("SubmitMiniProgOrder") || reqHeader.transType.equals("SubmitWXMiniProgOrder")) {
                        if (StringHelper.hasAnyChar(p_req.openid)) {
                            sbXml.append("  <openid>" + p_req.openid + "</openid>\r\n");
                            arrayParams.add("openid=" + p_req.openid);
                        } else {
                            if (StringHelper.isNullOrEmpty(p_req.code)) {
                                retAts.respCode = "-1";
                                retAts.respInfo = "Code和Openid不能同时为空";

                                return retAts;
                            } else {
                                if (StringHelper.isNullOrEmpty(actItem.appSecret)) {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "未配置公众号的appsecret";

                                    return retAts;
                                } else {
                                    HashMap<String, String> hashOpenid = getOpenid(appid, actItem.appSecret, p_req.code);

                                    if (hashOpenid.get("RespCode").equals("0")) {
                                        if (hashOpenid.containsKey("openid")) {
                                            sbXml.append("  <openid>" + hashOpenid.get("openid") + "</openid>\r\n");
                                            arrayParams.add("openid=" + hashOpenid.get("openid"));
                                        } else {
                                            retAts.respCode = "-1";
                                            retAts.payInfoCode = FailCode.E9981;

                                            String errcode = "";
                                            if (hashOpenid.containsKey("errcode")) {
                                                errcode = hashOpenid.get("errcode");
                                            }

                                            String errmsg = "";
                                            if (hashOpenid.containsKey("errmsg")) {
                                                errmsg = hashOpenid.get("errmsg");
                                            }

                                            retAts.respInfo = StringHelper.joinNotEmpty("-", errcode, errmsg);
                                            retAts.transState = PaymentState.FAIL_Payment;

                                            return retAts;
                                        }
                                    } else {
                                        retAts.respCode = "-1";
                                        retAts.respInfo = hashOpenid.get("RespInfo");

                                        return retAts;
                                    }
                                }
                            }
                        }

                        if ("1".equals(p_req.realNameFlag)) {
                            if (StringHelper.hasAnyChar(p_req.region)) {
                                sbXml.append("  <region>" + p_req.region + "</region>\r\n");
                                arrayParams.add("region=" + p_req.region);
                            }

                            if (StringHelper.hasAnyChar(p_req.circPaymentNo)) {
                                sbXml.append("  <circ_payment_no>" + p_req.circPaymentNo + "</circ_payment_no>\r\n");
                                arrayParams.add("circ_payment_no=" + p_req.circPaymentNo);
                            }

                            if ("2".equals(p_req.realNameType) || "440300".equals(p_req.region)) {
                                if (StringHelper.hasAnyChar(p_req.corpNo)) {
                                    sbXml.append("  <agency_code>" + p_req.corpNo + "</agency_code>\r\n");
                                    arrayParams.add("agency_code=" + p_req.corpNo);
                                } else {
                                    String corpNo = getBankConfig().getValueAsString("corpNo");
                                    if (StringHelper.hasAnyChar(corpNo)) {
                                        sbXml.append("  <agency_code>" + corpNo + "</agency_code>\r\n");
                                        arrayParams.add("agency_code=" + corpNo);
                                    }
                                }

                                StringBuilder encryptMsg = new StringBuilder();
                                encryptMsg.append("name=").append(p_req.oppActName).append("&");
                                encryptMsg.append("id_code=").append(p_req.certNumber).append("&");
                                encryptMsg.append("bill_no=").append(p_req.insuPolicyNum);
                                WriteBankLogLn2("公众号实名身份验证信息明文:\r\n" + encryptMsg.toString());

                                String insurancekey = actItem.saltKey.substring(actItem.saltKey.length() - 16);
                                String encryptResult = encrypt(encryptMsg.toString(), insurancekey);
                                if (StringHelper.hasAnyChar(encryptResult)) {
                                    sbXml.append("  <extend>" + encryptResult + "</extend>\r\n");
                                    arrayParams.add("extend=" + encryptResult);
                                }
                            }
                            if (StringHelper.hasAnyChar(p_req.realNameType) || (StringHelper.hasAnyChar(p_req.region) || StringHelper.hasAnyChar(p_req.circPaymentNo))) {
                                submitUrl = "realnameJSAPIOrder";
                            }
                        }
                    }
                }

                String nonce_str = get_nonce_str();
                sbXml.append("  <nonce_str>" + nonce_str + "</nonce_str>\r\n");
                arrayParams.add("nonce_str=" + nonce_str);

                if (StringHelper.hasAnyChar(p_req.description)) {
                    String body = XmlHelper.encode(p_req.description);
                    sbXml.append("  <body>" + body + "</body>\r\n");
                    arrayParams.add("body=" + body);
                }

                sbXml.append("  <out_trade_no>" + p_req.rdSeq + "</out_trade_no>\r\n");
                arrayParams.add("out_trade_no=" + p_req.rdSeq);

                if (StringHelper.hasAnyChar(p_req.attach)) {
                    sbXml.append("  <attach>" + p_req.attach + "</attach>\r\n");
                    arrayParams.add("attach=" + p_req.attach);
                }

                if (StringHelper.hasAnyChar(p_req.amount)) {
                    String total_fee = StringHelper.amountMultiply100(p_req.amount);
                    sbXml.append("  <total_fee>" + total_fee + "</total_fee>\r\n");
                    arrayParams.add("total_fee=" + total_fee);
                }

                if (StringHelper.hasAnyChar(p_req.timeStart)) {
                    sbXml.append("  <time_start>" + p_req.timeStart + "</time_start>\r\n");
                    arrayParams.add("time_start=" + p_req.timeStart);
                }
                if (StringHelper.hasAnyChar(p_req.timeExpire)) {
                    sbXml.append("  <time_expire>" + p_req.timeExpire + "</time_expire>\r\n");
                    arrayParams.add("time_expire=" + p_req.timeExpire);
                }

                String limitPay = "";
                if (StringHelper.hasAnyChar(p_req.isLimitCredit)) {
                    if ("1".equals(limitPay)) {
                        limitPay = "no_credit";
                    }
                } else {
                    limitPay = getBankConfig().getValueAsString("limitPay");
                    if (!"no_credit".equals(limitPay)) {
                        limitPay = "";
                    }
                }
                if (StringHelper.hasAnyChar(limitPay)) {
                    sbXml.append("  <limit_pay>" + limitPay + "</limit_pay>\r\n");
                    arrayParams.add("limit_pay=" + limitPay);
                }

                if (StringHelper.hasAnyChar(p_req.productId)) {
                    sbXml.append("  <product_id>" + p_req.productId + "</product_id>\r\n");
                    arrayParams.add("product_id=" + p_req.productId);
                }

                String[] signParams = new String[arrayParams.size()];
                arrayParams.toArray(signParams);
                String sign = signMessage(signParams, actItem.saltKey);
                sbXml.append("  <sign>" + sign + "</sign>\r\n");
                sbXml.append("</xml>");

                String[] tmpStrRet = new String[]{"", ""};
                if ("realnameJSAPIOrder".equals(submitUrl)) {
                    tmpStrRet = sendToBank(sbXml.toString(), submitUrl, false);
                } else {
                    tmpStrRet = sendToBank(sbXml.toString(), submitUrl);
                }

                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String return_code = tmpBkReader.getFirstText("/xml/return_code");
                        String return_msg = tmpBkReader.getFirstText("/xml/return_msg");
                        String result_code = tmpBkReader.getFirstText("/xml/result_code");
                        if (return_code != null && return_code.equals("SUCCESS")) {
                            if (result_code != null && result_code.equals("SUCCESS")) {
                                boolean verifyResult = this.verifySign(tmpStrRet[1], actItem.saltKey, tmpSbMsg);
                                if (verifyResult) {
                                    retAts.respCode = "0";
                                    retAts.transState = "SUCCESS";
                                    if (p_req.qrMode.equals("2")) {
                                        retAts.qrType = "";
                                        retAts.qrInfo = tmpBkReader.getFirstText("/xml/code_url");
                                    } else {
                                        if (p_req.reqHeader.transType.equals("SubmitQROrder")) {
                                            retAts.customHashMap = new HashMap<String, String>();
                                            retAts.customHashMap.put("prepay_id", tmpBkReader.getFirstText("/xml/prepay_id"));
                                            retAts.customHashMap.put("return_code", return_code);
                                            retAts.customHashMap.put("appid", appid);
                                            retAts.customHashMap.put("mch_id", mch_id);

                                            nonce_str = get_nonce_str();
                                            retAts.customHashMap.put("nonce_str", nonce_str);
                                            retAts.customHashMap.put("result_code", "SUCCESS");

                                            String[] retSignParams = new String[retAts.customHashMap.size()];
                                            int idx = 0;
                                            Iterator<String> iter = retAts.customHashMap.keySet().iterator();
                                            while (iter.hasNext()) {
                                                String eachKey = iter.next();
                                                retSignParams[idx] = eachKey + "=" + retAts.customHashMap.get(eachKey);
                                                idx++;
                                            }
                                            String retSign = signMessage(retSignParams, actItem.saltKey);
                                            retAts.customHashMap.put("sign", retSign);
                                        } else if (p_req.reqHeader.transType.equals("SubmitJSAPIOrder") || reqHeader.transType.equals("SubmitMiniProgOrder") || reqHeader.transType.equals("SubmitWXMiniProgOrder")) {
                                            retAts.customHashMap = new HashMap<String, String>();
                                            retAts.customHashMap.put("appId", appid);
                                            String timeStamp = DateHelper.getSecsFrom1970();
                                            retAts.customHashMap.put("timeStamp", timeStamp);
                                            nonce_str = get_nonce_str();
                                            retAts.customHashMap.put("nonceStr", nonce_str);
                                            retAts.customHashMap.put("package", "prepay_id=" + tmpBkReader.getFirstText("/xml/prepay_id"));
                                            retAts.customHashMap.put("signType", "MD5");
                                            String[] retSignParams = new String[retAts.customHashMap.size()];
                                            int idx = 0;
                                            Iterator<String> iter = retAts.customHashMap.keySet().iterator();
                                            while (iter.hasNext()) {
                                                String eachKey = iter.next();
                                                retSignParams[idx] = eachKey + "=" + retAts.customHashMap.get(eachKey);
                                                idx++;
                                            }
                                            String retSign = signMessage(retSignParams, actItem.saltKey);
                                            retAts.customHashMap.put("paySign", retSign);
                                        } else if (p_req.reqHeader.transType.equals("SubmitH5Order")) {
                                            retAts.customHashMap = new HashMap<String, String>();
                                            String mWebURL = tmpBkReader.getFirstText("/xml/mweb_url");
                                            if (p_req.needReturnURL) {
                                                String redirectUrl = getBankConfig().getValueAsString("redirectUrl");
                                                if (StringHelper.isNullOrEmpty(redirectUrl)) {
                                                    redirectUrl = bankFront.getUrl("redirectUrl");
                                                }
                                                if (StringHelper.hasAnyChar(redirectUrl)) {
                                                    redirectUrl += "?rdseq=" + p_req.rdSeq;
                                                    mWebURL = mWebURL + "&redirect_url=" + URLEncoder.encode(redirectUrl, getCharset());
                                                }
                                            }
                                            retAts.customHashMap.put("MWebURL", mWebURL);
                                        } else if (p_req.reqHeader.transType.equals("SubmitAPPOrder")) {
                                            HashMap<String, String> signMapParams = new HashMap<String, String>();

                                            signMapParams.put("appid", appid);
                                            signMapParams.put("partnerid", mch_id);
                                            String prepayId = tmpBkReader.getFirstText("/xml/prepay_id");
                                            signMapParams.put("prepayid", prepayId);
                                            signMapParams.put("package", "Sign=WXPay");

                                            nonce_str = get_nonce_str();
                                            signMapParams.put("noncestr", nonce_str);

                                            String timeStamp = DateHelper.getSecsFrom1970();
                                            signMapParams.put("timestamp", timeStamp);

                                            String[] retSignParams = new String[signMapParams.size()];
                                            int idx = 0;
                                            Iterator<String> iter = signMapParams.keySet().iterator();
                                            while (iter.hasNext()) {
                                                String eachKey = iter.next();
                                                retSignParams[idx] = eachKey + "=" + signMapParams.get(eachKey);
                                                idx++;
                                            }
                                            String retSign = signMessage(retSignParams, actItem.saltKey);

                                            retAts.customHashMap = new HashMap<String, String>();
                                            retAts.customHashMap.put("AppId", appid);
                                            retAts.customHashMap.put("PartnerID", mch_id);
                                            retAts.customHashMap.put("PrePayId", prepayId);
                                            retAts.customHashMap.put("NonceStr", nonce_str);
                                            retAts.customHashMap.put("Package", "Sign=WXPay");
                                            retAts.customHashMap.put("TimeStamp", timeStamp);
                                            retAts.customHashMap.put("Sign", retSign);
                                        }
                                    }
                                } else {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = tmpSbMsg.toString();
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = tmpBkReader.getFirstText("/xml/err_code_des");
                                if (StringHelper.hasAnyChar(tmpBkReader.getFirstText("/xml/return_msg"))) {
                                    retAts.respInfo = tmpBkReader.getFirstText("/xml/return_msg");
                                }
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.transState = return_code;
                            retAts.respInfo = return_msg;
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            } else {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号[" + p_req.ownAct + "]商户配置信息!";
                retAts.transState = PaymentState.FAIL;
                retAts.payInfoCode = FailCode.E9981;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsQueryOrder queryUnifiedOrder(ReqQueryOrder p_req) {
        RetAtsQueryOrder retAts = new RetAtsQueryOrder();
        retAts.rdSeq = p_req.rdSeq;

        try {
            ActSetItem actItem = getBankConfig().getActSetItemByAny(p_req.ownAct, p_req.merchantId, p_req.appId, "unifiedorder");
            if (actItem != null) {
                ArrayList<String> arrayParams = new ArrayList<String>();

                StringBuilder sbXml = new StringBuilder();
                sbXml.append("<xml>\r\n");

                String appid = p_req.appId;
                if (StringHelper.isNullOrEmpty(appid)) {
                    appid = actItem.appId;
                }
                sbXml.append("  <appid>" + appid + "</appid>\r\n");
                arrayParams.add("appid=" + appid);

                String mch_id = p_req.merchantId;
                if (StringHelper.isNullOrEmpty(mch_id)) {
                    mch_id = actItem.merchantId;
                }
                sbXml.append("  <mch_id>" + mch_id + "</mch_id>\r\n");
                arrayParams.add("mch_id=" + mch_id);

                sbXml.append("  <out_trade_no>" + p_req.rdSeq + "</out_trade_no>\r\n");
                arrayParams.add("out_trade_no=" + p_req.rdSeq);

                String nonce_str = get_nonce_str();
                sbXml.append("  <nonce_str>" + nonce_str + "</nonce_str>\r\n");
                arrayParams.add("nonce_str=" + nonce_str);

                String[] signParams = new String[arrayParams.size()];
                arrayParams.toArray(signParams);
                String sign = signMessage(signParams, actItem.saltKey);
                sbXml.append("  <sign>" + sign + "</sign>\r\n");
                sbXml.append("</xml>");

                String[] tmpStrRet = sendToBank(sbXml.toString(), "orderquery");

                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String return_code = tmpBkReader.getFirstText("/xml/return_code");
                        String return_msg = tmpBkReader.getFirstText("/xml/return_msg");
                        if (return_code != null && return_code.equals("SUCCESS")) {
                            boolean verifyResult = this.verifySign(tmpStrRet[1], actItem.saltKey, tmpSbMsg);
                            if (verifyResult) {
                                String result_code = tmpBkReader.getFirstText("/xml/result_code");
                                String err_code = tmpBkReader.getFirstText("/xml/err_code");
                                String trade_state = tmpBkReader.getFirstText("/xml/trade_state");
                                retAts.respCode = "0";
                                retAts.transState = StringHelper.joinNotEmpty("+", result_code, err_code, trade_state);
                                String out_trade_no = tmpBkReader.getFirstText("/xml/out_trade_no");
                                if (StringHelper.hasAnyChar(out_trade_no)) {
                                    if (!out_trade_no.equals(p_req.rdSeq)) {
                                        retAts.respCode = "-1";
                                        retAts.respInfo = "请求流水号" + p_req.rdSeq + "与响应流水号" + out_trade_no + "不一致";
                                        return retAts;
                                    }
                                }

                                retAts.payInfoCode = StringHelper.joinNotEmpty("+", err_code, trade_state);

                                String err_code_des = tmpBkReader.getFirstText("/xml/err_code_des");
                                String trade_state_desc = tmpBkReader.getFirstText("/xml/trade_state_desc");
                                retAts.respInfo = StringHelper.joinNotEmpty("，", err_code_des, trade_state_desc);
                                retAts.oppBank = tmpBkReader.getFirstText("/xml/bank_type");
                                retAts.outTransID = tmpBkReader.getFirstText("/xml/transaction_id");
                                retAts.openId = tmpBkReader.getFirstText("/xml/openid");

                                if (retAts.payInfoCode == null) {
                                    retAts.payInfoCode = "";
                                }

                                if (retAts.respInfo == null) {
                                    retAts.respInfo = "";
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = tmpSbMsg.toString();
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = return_msg;
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_req.ownAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }
}